package br.uvv.sao.managedBean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.faces.model.SelectItem;

import org.primefaces.model.LazyDataModel;

import br.uvv.sao.domain.AlternativaBase;
import br.uvv.sao.domain.Disciplina;
import br.uvv.sao.domain.OfertaDisciplina;
import br.uvv.sao.domain.PalavraChave;
import br.uvv.sao.domain.Professor;
import br.uvv.sao.domain.Prova;
import br.uvv.sao.domain.Questao;
import br.uvv.sao.domain.QuestaoBase;
import br.uvv.sao.enums.TipoGrauDificuldade;
import br.uvv.sao.rn.ProvaRN;
import br.uvv.sao.util.InitUtil;
import br.uvv.sao.util.MsgUtil;
import br.uvv.sao.util.RNException;
import br.uvv.sao.util.Util;

public class ProvaBean implements Serializable {

	private static final long serialVersionUID = -5854720973184648590L;

	private Professor professorLogado;
	
	private ProvaRN provaRN = new ProvaRN();
	
	private Prova provaInstance;
	private Prova provaInstanceTemp;
	private QuestaoBase questaoBaseInstance;
	private Questao questaoInstance;
	
	private List<AlternativaBase> alternativaBaseList;
	private AlternativaBase alternativaBaseInstance;
	
	private PalavraChave assuntoInstance;
	private List<PalavraChave> palavraChaveList;
	
	private LazyDataModel<Prova> provaList;
	private LazyDataModel<Questao> questaoLazyList;
	
	private String varBuscaCodigo;
	private String varBuscaDescricao;
	
	private String varBuscaCabecalho;
	private Long varBuscaPalavraChave;
	
	//Referente a Busca de Ofertas de Disciplinas
	private ArrayList<Disciplina> disciplinaList;
	private Long idDisciplina;
	private String buscaSemestre;
	private Date buscaAno;
	private List<SelectItem> anosList;
	private LazyDataModel<OfertaDisciplina> ofertaLazyList;
	private OfertaDisciplina ofertaInstanceTemp;
	
	//Referente a Busca de Questões Base
	private String varCabecalho;
	private Long varIdAssunto;
	private TipoGrauDificuldade varDificuldade;
	private LazyDataModel<QuestaoBase> questaoBaseLazyList;
	
	//Referente a busca de palavra Chave
	private String nomePalavraChave;
	
	public String goProva(){
		init();
		return "/views/prova/show.xhtml";
	}
	
	private void init(){
		provaRN = new ProvaRN();
		professorLogado = (Professor) Util.getUsuarioLogado();
		provaInstance = new Prova();
		provaInstanceTemp = new Prova();
		questaoBaseInstance = new QuestaoBase();
		varBuscaCabecalho = "";
		varBuscaPalavraChave = null;
		questaoBaseLazyList = InitUtil.inicializaQuestaoBaseList();
		provaList = InitUtil.inicializaProvaList();
		questaoLazyList = InitUtil.inicializaQuestaoList();
		inicializaOfertaDisciplina();
	}
	
	public String goCreate(){
		provaInstance = new Prova();
		provaInstance.setCodigo(provaRN.gerarCodigoProva());
		provaInstance.setProfessor(professorLogado);
		provaInstance.setQuestoes(new ArrayList<Questao>());
		provaInstance.setAplicadaEm(new OfertaDisciplina());
		palavraChaveList = provaRN.listarPalavraChave(null);
		return "/views/prova/create.xhtml";
	}
	
	private void inicializaOfertaDisciplina(){
		ofertaInstanceTemp = new OfertaDisciplina();
		ofertaLazyList = InitUtil.inicializaOfertaDisciplinaList();
		try {
			disciplinaList = (ArrayList<Disciplina>) provaRN.listarDisciplinas();
		} catch (RNException e) {
		}
		idDisciplina = null;
		buscaAno = null;
		buscaSemestre = null;
	}
	
	public String goEdit(){
		provaInstanceTemp = provaInstance;
		return "/views/prova/edit.xhtml";
	}
	
	public String desistir(){
		return "/views/prova/show.xhtml";
	}
	
	public String salvar(){
		try {
			provaRN.salvar(provaInstance);
			MsgUtil.msgInfo("Sucesso!");
			return "/views/prova/show.xhtml";
		} catch (RNException e) {
			MsgUtil.msgError("Erro!");
			e.printStackTrace();
			return null;
		}
	}
	
	public void excluir(){
		try {
			provaRN.excluir(provaInstance);
			MsgUtil.msgInfo("Sucesso!");
		} catch (RNException e) {
			MsgUtil.msgError("ERRO!!!!");
			e.printStackTrace();
		}
	}
	
	@SuppressWarnings("serial")
	public void filtrarProva(){
		provaList = new LazyDataModel<Prova>() {
			@Override
			public List<Prova> load(int first, int pageSize, String sortField,
					boolean sortOrder, Map<String, String> arg4) {
				try {
					List<Prova> provaTemp = provaRN.listar(first, pageSize, sortField, sortOrder, varBuscaCodigo, varBuscaDescricao);
					for (Prova p:provaTemp){
						System.out.println(p.getCodigo());
					}
					return provaRN.listar(first, pageSize, sortField, sortOrder, varBuscaCodigo, varBuscaDescricao);
				} catch (RNException e) {
					e.printStackTrace();
					return null;
				}
			}
		};
		provaList.setPageSize(5);
	}
	
	public void selecionarProva(){
		try {
			provaInstance = provaRN.selecionar(provaInstanceTemp.getId());
			filtrarQuestao();
		} catch (RNException e) {
			MsgUtil.msgError("ERRO!!!!");
			e.printStackTrace();
		}
		cancelarSelecionarProva();
	}
	
	public void cancelarSelecionarProva(){
		provaList = InitUtil.inicializaProvaList();
	}
	
	@SuppressWarnings("serial")
	public void filtrarOfertaDisciplina(){
		ofertaLazyList = new LazyDataModel<OfertaDisciplina>() {
			@Override
			public List<OfertaDisciplina> load(int first, int pageSize, String sortField, boolean sortOrder, Map<String, String> filters) {
	        	Util.setDataTableRows(pageSize);
				try {
					return provaRN.listarOfertaDisciplina(first, pageSize, sortField, sortOrder, 
								idDisciplina, null, buscaSemestre, buscaAno);
				} catch (RNException e) {
					e.printStackTrace();
					return null;
				}
			}
		};
		ofertaLazyList.setPageSize(5);
	}
	
	public void selecionarOfertaDisciplina(){
		provaInstance.setAplicadaEm(ofertaInstanceTemp);
	}
	
	public void cancelarSelecionarOfertaDisciplina(){
		inicializaOfertaDisciplina();
	}
	
	@SuppressWarnings("serial")
	private void filtrarQuestao(){
		questaoLazyList = new LazyDataModel<Questao>() {
			@Override
			public List<Questao> load(int first, int pageSize, String sortField, boolean sortOrder, Map<String, String> filters) {
	        	Util.setDataTableRows(pageSize);
				try {
					return provaRN.listarQuestao(first, pageSize, sortField, sortOrder, provaInstance.getId());
				} catch (RNException e) {
					e.printStackTrace();
					return null;
				}
			}
		};
		questaoLazyList.setPageSize(5);
	}
	
	
	
	/**
	 * Área referente a manutenção rápida de questões
	 */
	
	public void goCreateQuestaoBase(){
		questaoBaseInstance = new QuestaoBase();
		questaoBaseInstance.setCodigo(provaRN.gerarCodigoQuestaoBase());
		questaoBaseInstance.setProfessor(professorLogado);
		questaoBaseInstance.setAlternativas(new ArrayList<AlternativaBase>());
		questaoBaseInstance.setPalavraChave(new PalavraChave());
		alternativaBaseList = new ArrayList<AlternativaBase>();
		alternativaBaseInstance = new AlternativaBase();
	}
	
	public void autoCompletePalavraChave(){
		palavraChaveList = provaRN.listarPalavraChave(nomePalavraChave);
	}
	
	public void goDeleteQuestao(){
		//remover da lista de quesões
	}
	
	public void salvarQuestaoBase(){
		try {
			provaRN.salvarQuestaoBase(questaoBaseInstance);
			MsgUtil.msgInfo("A questão '" + questaoInstance.getCodigo() + "' foi criada com sucesso!");
		} catch (RNException e){
			MsgUtil.msgInfo("Ocorreu um erro ao criar a questão '" + questaoInstance.getCodigo() + "'!");
		}
		//Adicionar na lista
	}
	
	@SuppressWarnings("serial")
	public void filtrarQuestaoBase(){
		questaoBaseLazyList = new LazyDataModel<QuestaoBase>() {
			@Override
			public List<QuestaoBase> load(int first, int pageSize, String sortField, boolean sortOrder, Map<String, String> filters) {
	        	Util.setDataTableRows(pageSize);
				try {
					return provaRN.listarQuestaoBase(first, pageSize, sortField, sortOrder, varCabecalho, varDificuldade, varIdAssunto);
				} catch (RNException e) {
					e.printStackTrace();
					return null;
				}
			}
		};
		questaoBaseLazyList.setPageSize(5);
	}
	
	public void selecionarQuestaoBase(){
		questaoInstance = provaRN.transformarQuestaoBaseEmQuestao(questaoBaseInstance);
		provaInstance.getQuestoes().add(questaoInstance);
	}
	
	public void cancelarSelecionarQuestaoBase(){
		
	}
	
	
	/**
	 * Área referente a manutenção rápida de alternativas
	 */
	public void goCreateAlternativaBase(){
		alternativaBaseInstance = new AlternativaBase();
	}
	
	public void salvarAlternativaBase(){
		//Apenas adicionar no arrayList da questaoem edicao;
	}
	
	public void goEditAlternativaBase(){ }
	
	public void goDeleteAlternativaBase(){
		//remover da lista de alterantivas
	}
	
	public void marcarAlternativaCorreta(){
		//marcar
	}
	
	/**
	 * Área referente ao cadastro rápido de assuntos
	 */
	public void goCreateAssunto(){
		assuntoInstance = new PalavraChave();
	}
	
	public void salvarAssunto(){
		try {
			provaRN.salvarAssunto(assuntoInstance);
			MsgUtil.msgInfo("O assunto '" + assuntoInstance.getNome() + "' foi criado com sucesso!");
		} catch (RNException e){
			MsgUtil.msgInfo("Ocorreu um erro ao criar o assunto '" + assuntoInstance.getNome() + "'!");
		}
	}
	
	public Boolean getTestaAlterantivaCorreta(String texto){
		if (questaoInstance.getAlternativaCorreta() != null){
			AlternativaBase alternativaCorreta = new AlternativaBase();
			if (alternativaCorreta.getTexto().equals(texto))
				return true;
		}
		return false;
	}
	
	public String goHome(){
		return "goHome";
	}
	
	public Prova getProvaInstance() {
		return provaInstance;
	}

	public void setProvaInstance(Prova provaInstance) {
		this.provaInstance = provaInstance;
	}

	public Prova getProvaInstanceTemp() {
		return provaInstanceTemp;
	}

	public void setProvaInstanceTemp(Prova provaInstanceTemp) {
		this.provaInstanceTemp = provaInstanceTemp;
	}

	public LazyDataModel<Prova> getProvaList() {
		return provaList;
	}

	public void setProvaList(LazyDataModel<Prova> provaList) {
		this.provaList = provaList;
	}

	public QuestaoBase getQuestaoBaseInstance() {
		return questaoBaseInstance;
	}

	public void setQuestaoBaseInstance(QuestaoBase questaoBaseInstance) {
		this.questaoBaseInstance = questaoBaseInstance;
	}
	
	public LazyDataModel<QuestaoBase> getQuestaoBaseLazyList() {
		return questaoBaseLazyList;
	}
	
	public void setQuestaoBaseLazyList(
			LazyDataModel<QuestaoBase> questaoBaseLazyList) {
		this.questaoBaseLazyList = questaoBaseLazyList;
	}

	public String getVarBuscaCabecalho() {
		return varBuscaCabecalho;
	}

	public void setVarBuscaCabecalho(String varBuscaCabecalho) {
		this.varBuscaCabecalho = varBuscaCabecalho;
	}

	public Long getVarBuscaPalavraChave() {
		return varBuscaPalavraChave;
	}

	public void setVarBuscaPalavraChave(Long varBuscaPalavraChave) {
		this.varBuscaPalavraChave = varBuscaPalavraChave;
	}
	
	public Questao getQuestaoInstance() {
		return questaoInstance;
	}
	
	public void setQuestaoInstance(Questao questaoInstance) {
		this.questaoInstance = questaoInstance;
	}
	
	public LazyDataModel<Questao> getQuestaoLazyList() {
		return questaoLazyList;
	}
	
	public void setQuestaoLazyList(LazyDataModel<Questao> questaoLazyList) {
		this.questaoLazyList = questaoLazyList;
	}
	
	public String getVarBuscaCodigo() {
		return varBuscaCodigo;
	}
	
	public void setVarBuscaCodigo(String varBuscaCodigo) {
		this.varBuscaCodigo = varBuscaCodigo;
	}
	
	public String getVarBuscaDescricao() {
		return varBuscaDescricao;
	}
	
	public void setVarBuscaDescricao(String varBuscaDescricao) {
		this.varBuscaDescricao = varBuscaDescricao;
	}
	
	public List<SelectItem> getAnosList() {
		anosList = new ArrayList<SelectItem>();
		for (Integer i=2010; i<2025; i++){
			anosList.add(new SelectItem("02/02/"+i, i.toString()));
		}
		return anosList;
	}

	public ProvaRN getProvaRN() {
		return provaRN;
	}

	public void setProvaRN(ProvaRN provaRN) {
		this.provaRN = provaRN;
	}

	public ArrayList<Disciplina> getDisciplinaList() {
		return disciplinaList;
	}

	public void setDisciplinaList(ArrayList<Disciplina> disciplinaList) {
		this.disciplinaList = disciplinaList;
	}
	
	public Long getIdDisciplina() {
		return idDisciplina;
	}
	
	public void setIdDisciplina(Long idDisciplina) {
		this.idDisciplina = idDisciplina;
	}

	public String getBuscaSemestre() {
		return buscaSemestre;
	}

	public void setBuscaSemestre(String buscaSemestre) {
		this.buscaSemestre = buscaSemestre;
	}
	
	public Date getBuscaAno() {
		return buscaAno;
	}
	
	public void setBuscaAno(Date buscaAno) {
		this.buscaAno = buscaAno;
	}

	public void setAnosList(List<SelectItem> anosList) {
		this.anosList = anosList;
	}
	
	public OfertaDisciplina getOfertaInstanceTemp() {
		return ofertaInstanceTemp;
	}
	
	public void setOfertaInstanceTemp(OfertaDisciplina ofertaInstanceTemp) {
		this.ofertaInstanceTemp = ofertaInstanceTemp;
	}
	
	public LazyDataModel<OfertaDisciplina> getOfertaLazyList() {
		return ofertaLazyList;
	}
	
	public void setOfertaLazyList(LazyDataModel<OfertaDisciplina> ofertaLazyList) {
		this.ofertaLazyList = ofertaLazyList;
	}
	
	public Professor getProfessorLogado() {
		return professorLogado;
	}
	
	public void setProfessorLogado(Professor professorLogado) {
		this.professorLogado = professorLogado;
	}
	
	public String getVarCabecalho() {
		return varCabecalho;
	}
	
	public void setVarCabecalho(String varCabecalho) {
		this.varCabecalho = varCabecalho;
	}
	
	public TipoGrauDificuldade getVarDificuldade() {
		return varDificuldade;
	}
	
	public void setVarDificuldade(TipoGrauDificuldade varDificuldade) {
		this.varDificuldade = varDificuldade;
	}
	
	public Long getVarIdAssunto() {
		return varIdAssunto;
	}
	
	public void setVarIdAssunto(Long varIdAssunto) {
		this.varIdAssunto = varIdAssunto;
	}
	
	public PalavraChave getAssuntoInstance() {
		return assuntoInstance;
	}
	
	public void setAssuntoInstance(PalavraChave assuntoInstance) {
		this.assuntoInstance = assuntoInstance;
	}
	
	public List<PalavraChave> getPalavraChaveList() {
		return palavraChaveList;
	}
	
	public void setPalavraChaveList(List<PalavraChave> palavraChaveList) {
		this.palavraChaveList = palavraChaveList;
	}
	
	public AlternativaBase getAlternativaBaseInstance() {
		return alternativaBaseInstance;
	}
	
	public void setAlternativaBaseInstance(
			AlternativaBase alternativaBaseInstance) {
		this.alternativaBaseInstance = alternativaBaseInstance;
	}
	
	public List<AlternativaBase> getAlternativaBaseList() {
		return alternativaBaseList;
	}
	
	public void setAlternativaBaseList(List<AlternativaBase> alternativaBaseList) {
		this.alternativaBaseList = alternativaBaseList;
	}
	
	public String getNomePalavraChave() {
		return nomePalavraChave;
	}
	
	public void setNomePalavraChave(String nomePalavraChave) {
		this.nomePalavraChave = nomePalavraChave;
	}
	
}